package com.wedimob.scrapper.data;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jsoup.Connection.Response;

import com.wedimob.scrapper.parser.Parser;

/**
 * 
 * @author melouadi
 * 
 *            storage type
 */
public class ContentStore implements Iterable<Content> {

	/** basic factory.
	 * 
	 * @param aParser parser
	 * @return store
	 */
	public static ContentStore create(
			final Parser<?> aParser) {
		return new ContentStore(aParser);
	}

	/**
	 * transformation.
	 */
	private Parser<?> parser;

	/**
	 * indexed store.
	 */
	private Map<URI, Content> store = new HashMap<URI, Content>();

	/**
	 * flat store.
	 */
	private List<Content> contents = new ArrayList<Content>();

	/**
	 * minimal constructor.
	 * 
	 * @param aParser
	 *            parser
	 */
	public ContentStore(final Parser<?> aParser) {
		parser = aParser;
	}

	/**
	 * add content to store.
	 * 
	 * @param content
	 *            aContent
	 */
	public final void addContent(final Content content) {
		if (!store.containsKey(content.getUri())) {
			Content obj = parser.parse(content);
			store.put(content.getUri(), obj);
			contents.add(obj);
		}
	}

	/**
	 * retrieve content for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return content
	 */
	public final Content getContent(final URI uri) {
		Content content = store.get(uri);
		if (content == null) {
			throw new RuntimeException("Store does not contain " + uri);
		}
		return content;
	}

	/**
	 * retrieve error status for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return status
	 */
	public final boolean hasError(final URI uri) {
		return (getContent(uri).getError() != null);
	}

	/**
	 * retrieve error for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return error
	 */
	public final Throwable getError(final URI uri) {
		return getContent(uri).getError();
	}

	/**
	 * retrieve response for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return response
	 */
	public final Response getResponse(final URI uri) {
		return getContent(uri).getResponse();
	}

	/**
	 * retrieve error status for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return status
	 */
	public final boolean hasError(final String uri) {
		return hasError(URI.create(uri));
	}

	/**
	 * retrieve error for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return error
	 */
	public final Throwable getError(final String uri) {
		return getError(URI.create(uri));
	}

	/**
	 * retrieve response for a given source.
	 * 
	 * @param uri
	 *            source
	 * @return response
	 */
	public final Response getResponse(final String uri) {
		return getResponse(URI.create(uri));
	}

	@Override
	public final Iterator<Content> iterator() {
		return contents.iterator();
	}

	/**
	 * number of content.
	 * 
	 * @return size
	 */
	public final int size() {
		return contents.size();
	}
}
